package com.rzico.sbl.ui

import android.Manifest
import android.app.Activity
import android.content.pm.ActivityInfo
import android.content.res.TypedArray
import android.os.*
import androidx.appcompat.app.AppCompatActivity
import com.fondesa.kpermissions.allGranted
import com.fondesa.kpermissions.anyPermanentlyDenied
import com.fondesa.kpermissions.extension.permissionsBuilder
import com.fondesa.kpermissions.extension.send
import com.lzg.OkGoHelper
import com.lzy.okgo.model.HttpMethod
import com.rzico.sbl.R
import com.rzico.sbl.model.BaseUrl
import com.rzico.sbl.model.Const
import com.rzico.sbl.other.*
import com.rzico.sbl.viewmodel.CommonViewModel
import com.xinnuo.common.extend.*
import com.xinnuo.common.helper.*
import com.xinnuo.common.helper.AppSettingHelper.goIntentSetting
import com.xinnuo.common_ui.utils.bindLifeCycle
import com.xinnuo.common_ui.utils.showHintDialog
import com.xinnuo.common_ui.utils.showOneHintDialog
import com.xinnuo.common_ui.utils.subscribeBySuccess
import com.xinnuo.objectbox.equalString
import com.xinnuo.objectbox.getBox
import com.xinnuo.objectbox.getBoxEuery
import com.xinnuo.objectbox.model.AppLoginData
import com.xinnuo.objectbox.model.AppLoginData_
import com.xinnuo.objectbox.model.UserLoginData
import com.xinnuo.objectbox.model.UserLoginData_
import org.json.JSONObject
import java.lang.reflect.Field
import java.lang.reflect.Method

/**
 * 不继承BaseActivity，解决打开显示空白的问题
 */
class GuideActivity : AppCompatActivity() {

    private val mViewModel by lazy { get<CommonViewModel>() }
    private var isReady: Boolean = false

    private var handler = object : Handler(Looper.myLooper()!!) {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)

            isReady.conditionElse(
                actionTrue = ::quitGuide,
                actionFalse = { isReady = true }
            )
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        // 解决android 8.0时screenOrientation垂直时崩溃的问题
        (Build.VERSION.SDK_INT == Build.VERSION_CODES.O
                && isTranslucentOrFloating()).condition { fixOrientation() }

        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_guide)

        ActivityStack.screenManager.pushActivity(this)

        window
            .decorView
            .postDelayed(
                { handler.sendEmptyMessage(0) },
                2000
            )

        requestPermission()
    }

    /**
     * 权限申请
     */
    private fun requestPermission() {
        permissionsBuilder(
            Manifest.permission.CAMERA,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_CALL_LOG
        )
            .build()
            .send {
                when {
                    it.allGranted() -> {
                        setCommonHeader()
                        handler.sendEmptyMessage(0)
                    }
                    it.anyPermanentlyDenied() -> {
                        showHintDialog(
                            hint = "所需权限被禁止开启，请前往设置页面手动开启",
                            sure = "去设置",
                            cancel = "再想想",
                            isForced = true,
                            onSure = {
                                goIntentSetting()

                                ActivityStack
                                    .screenManager
                                    .popActivities(this::class.java)
                            },
                            onCancel = {
                                ActivityStack
                                    .screenManager
                                    .popActivities(this::class.java)
                            }
                        )
                    }
                    else -> {
                        shortToast("请求权限被拒绝，请确保所需权限已开启")

                        ActivityStack
                            .screenManager
                            .popActivities(this::class.java)
                    }
                }
            }
    }

    /**
     * OkGo公共请求头设置
     */
    private fun setCommonHeader() {
        // 设置请求头参数
        OkGoHelper
            .commonHeaders {
                val uid = getDeviceId()
                val time = System.currentTimeMillis().toString()

                put("x-uid", uid)
                put("x-app", packageName)
                put("x-tsp", time)
                put("x-tkn", MD5.md5(uid + packageName + time + Const.APP_HEADER_KEY))

                isLogin.condition {
                    put("x-mid", getString("uid"))
                }
            }
    }

    /**
     * 退出启动页
     */
    private fun quitGuide() {
        isLogin.conditionElse(
            actionTrue = ::checkStatus,
            actionFalse = {
                startActivityEx<LoginActivity>()

                finishView()
            }
        )
    }

    /**
     * 检查登录状态
     */
    private fun checkStatus() {
        mViewModel.requestBind(
            isLoading = false,
            requestUrl = BaseUrl.loginCheck,
        )
            .bindLifeCycle(this)
            .subscribeBySuccess(
                event = mViewModel,
                onSuccess = {
                    val obj = JSONObject(it)
                    obj.optBoolean("loginStatus")
                        .conditionElse(
                            actionTrue = {
                                putShared("userSign", obj.optNotNull("userSig"))
                                window.decorView.post { getShopStatus() }
                            },
                            actionFalse = {
                                startActivityEx<LoginActivity>("offLine" to true)

                                finishView()
                            }
                        )
                },
                onError = {
                    startActivityEx<LoginActivity>("offLine" to true)

                    finishView()
                }
            )
    }

    /**
     * 检查店铺状态
     */
    private fun getShopStatus() {
        mViewModel
            .request(
                isLoadingBefore = false,
                isLoadingAfter = false,
                requestUrl = BaseUrl.shop,
                requestMethod = HttpMethod.GET,
                onSuccess = {
                    val obj = JSONObject(it)

                    val shopId = obj.optNotEmpty("shopId", "0")
                    val shopName = obj.optNotNull("shopName")
                    val shopStatus = obj.optNotNull("status")
                    val expireDay = obj.optInt("expire", 365)
                    val privacy = obj.optNotEmpty("privacyStatus", "on")
                    val callStatus = obj.optNotNull("callOrder")
                    val canRob = obj.optBoolean("rob")
                    val isOpen = !obj.optBoolean("paused")
                    val isReal = obj.optBoolean("hasRealName")

                    putShared("shopId", shopId)
                    putShared("shopName", shopName)
                    putShared("shopStatus", shopStatus)
                    putShared("expireDay", expireDay)     //过期天数
                    putShared("privacyStatus", privacy)   //号码隐私保护
                    putShared("incomeStatus", callStatus) //手机来电接单
                    putShared("canRob", canRob)           //是否抢单
                    putShared("isOpen", isOpen)           //是否营业
                    putShared("isReal", isReal)           //是否实名

                    reportEnable = obj.optBoolean("phEnable")     //是否报货
                    driverEnable = obj.optBoolean("driverEnable") //是否纯司机

                    // 店铺时间配置
                    val objTimeStr = obj.optNotEmpty("shippingConfig", "{}")
                    val objTime = JSONObject(objTimeStr)
                    val orderWarn = objTime.optNotNull("orderOvertime")
                    putShared("configJson", objTimeStr) //店铺时间配置
                    putShared("orderWarn", orderWarn)   //订单超时时间

                    // 角色属性
                    val objRole = obj.optJSONObject("roles") ?: JSONObject()
                    userRole = objRole.optNotNull("id")
                    roleName = objRole.optNotNull("name")

                    // 服务商属性
                    val objOperate = obj.optJSONObject("operate") ?: JSONObject()
                    serviceId = objOperate.optNotNull("id")
                    serviceStep = objOperate.optNotNull("step")

                    // 保存用户信息
                    getBox<UserLoginData>()
                        .apply {
                            query()
                                .equalString(
                                    UserLoginData_.uid,
                                    getBoxEuery<AppLoginData>()
                                        .equal(AppLoginData_.isLogin, true)
                                        .build()
                                        .findFirst()
                                        ?.uid ?: ""
                                )
                                .build()
                                .findFirst()
                                ?.let { item ->
                                    item.shopId = shopId
                                    item.shopName = shopName
                                    item.shopStatus = shopStatus
                                    item.privacyStatus = privacy
                                    item.callTelStatus = callStatus.intValue
                                    item.canRob = canRob
                                    item.isOpen = isOpen
                                    item.isReal = isReal
                                    // 报货属性
                                    item.reportEnable = reportEnable
                                    item.driverEnable = driverEnable
                                    // 店铺时间配置
                                    item.expireDay = expireDay
                                    item.configJson = objTimeStr
                                    item.orderWarn = orderWarn
                                    // 角色属性
                                    item.userRole = objRole.optNotNull("id")
                                    item.roleName = objRole.optNotNull("name")
                                    // 服务商属性
                                    item.serviceId = objOperate.optNotNull("id")
                                    item.serviceStep = objOperate.optNotNull("step")

                                    put(item)
                                }
                        }

                    when (shopStatus) {
                        "success" ->
                            getInt("expireDay")
                                .also { rest ->
                                    when (rest) {
                                        1, 2, 3, 5, 10, 15 -> showHintDialog(rest)
                                        in 4..Int.MAX_VALUE -> mainPage()
                                        else -> showHintDialog(rest)
                                    }
                                }

                        else -> {
                            startActivityEx<OpenActivity>()

                            finishView()
                        }
                    }
                }
            )
    }

    private fun showHintDialog(day: Int) {
        showOneHintDialog(
            isForced = true,
            hint = when (day) {
                in 1..15 -> "您的账户还有${day}天即将到期，未避免影响正常使用，请联系服务商及时续费！"
                else -> "您的账户因欠费已停止服务，请联系服务商续费后恢复使用！"
            },
            onResult = {
                (day in 1..15)
                    .conditionElse(
                        actionTrue = ::mainPage,
                        actionFalse = {
                            startActivityEx<LoginActivity>("offLine" to true)
                        }
                    )
            }
        )
    }

    private fun mainPage() {
        startActivityEx<MainActivity>()

        finishView()
    }

    override fun onBackPressed() {}

    private fun finishView() {
        ActivityStack
            .screenManager
            .popActivities(this::class.java)
    }

    /**
     * android 8.0时，是否是透明主题
     */
    private fun isTranslucentOrFloating(): Boolean {
        var isTranslucentOrFloating = false
        try {
            val styleableRes =
                Class.forName("com.android.internal.R\$styleable")
                    .getField("Window")[null] as IntArray
            val ta = obtainStyledAttributes(styleableRes)
            val method: Method =
                ActivityInfo::class.java.getMethod(
                    "isTranslucentOrFloating",
                    TypedArray::class.java
                )
            method.isAccessible = true
            isTranslucentOrFloating = method.invoke(null, ta) as Boolean
            method.isAccessible = false
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return isTranslucentOrFloating
    }

    /**
     * kotlin.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
     * <p>
     * 修复android 8.0存在的问题，设置屏幕不固定
     * <p>
     * 在Activity中onCreate()中super之前调用
     */
    private fun fixOrientation(): Boolean {
        try {
            val field: Field = Activity::class.java.getDeclaredField("mActivityInfo")
            field.isAccessible = true
            (field.get(this) as ActivityInfo)
                .screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
            field.isAccessible = false
            return true
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return false
    }

    /**
     * android 8.0在设置方向的时候如果透明，直接不执行
     */
    override fun setRequestedOrientation(requestedOrientation: Int) {
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O
            && isTranslucentOrFloating()
        ) return
        super.setRequestedOrientation(requestedOrientation)
    }

}